import type { Metadata } from 'next'; import Link from 'next/link'; import { AsnBgpChart } from '@/components/detail/AsnBgpChart'; import { ComponentGrid } from '@/components/detail/ComponentGrid'; import { ScopeHeader } from '@/components/detail/ScopeHeader'; import { ScopePressureChart } from '@/components/detail/ScopeCharts'; import { TargetsTable } from '@/components/detail/Tables'; import { IncidentsSection } from '@/components/incidents/IncidentsSection'; import { Section, Stat } from '@/components/ui/primitives'; import { apiGet, apiTry } from '@/lib/api'; import { fmt, fmtDelta, fmtInt, fmtPct, fmtRatio } from '@/lib/format'; import type { AsnDetail } from '@/lib/types'; export const dynamic = 'force-dynamic'; type Params = Promise<{ asn: string }>; export async function generateMetadata({ params }: { params: Params }): Promise { const { asn } = await params; const a = await apiTry(`/api/v1/pressure/asn/${encodeURIComponent(asn)}`); if (!a) return { title: `AS${asn}` }; return { title: `AS${a.asn} ${a.name} — pressure ${fmt(a.pressure)} (${a.level_label})`, description: `Independent observation of AS${a.asn} (${a.name}): pressure ${fmt(a.pressure)}, BGP churn ${fmtRatio(a.bgp.churn_ratio)}, path stability ${fmtPct(a.bgp.path_stability)}.`, alternates: { canonical: `/asn/${a.asn}` } }; } export default async function AsnPage({ params }: { params: Params }) { const { asn } = await params; if (!/^\d+$/.test(asn)) { const { notFound } = await import('next/navigation'); notFound(); } const a = await apiGet(`/api/v1/pressure/asn/${encodeURIComponent(asn)}`); return (
Observed from {a.regions_observed.length} probe regions · {fmtInt(a.targets.length)} targets announced from this network} pressure={a.pressure} level={a.level} delta1h={a.delta_1h} trend={a.trend} confidence={a.confidence} ts={a.ts} meta={ <> regions{' '} {a.regions_observed.map((r) => ( {r} ))} } />
global BGP dashboard →}>
= 2 ? 'var(--p-high)' : undefined }}>{fmtRatio(a.bgp.churn_ratio)}} sub="vs baseline" /> 0 ? 'var(--p-elevated)' : undefined }}>{fmtInt(a.bgp.origin_changes_1h)}} /> {fmtPct(a.bgp.path_stability)}} />
{fmtInt(a.targets.length)} targets · Δ1h {fmtDelta(a.delta_1h)}}>
); }